package com.xbongbong.paas.help.menu;

import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.service.init.AbstractInitMenuHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.pojo.dto.FormExplainAddDTO;
import com.xbongbong.paas.pojo.dto.MenuFormAddDTO;
import com.xbongbong.paas.pojo.dto.ProcessOpenDistributorDTO;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.service.PaasProcessTemplateService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.OrderCenterMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.form.pojo.dto.FormAddBatchDTO;
import com.xbongbong.pro.form.pojo.vo.FormAddBatchVO;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainAddBatchDTO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainAddBatchVO;
import com.xbongbong.pro.menu.pojo.dto.MenuFormAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuInitVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ReturnEnum;
import com.xbongbong.saas.help.BatchSeqExplainHelp;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *
 * @author wujian
 * @version v1.0
 * @date 2020/12/22 13:46
 * @since v1.0 订单中心应用生成和菜单初始化
 */

@Component
public class InitOrderCenterMenuHelp  extends AbstractInitMenuHelp{
    private static final Logger LOG = LoggerFactory.getLogger(InitOrderCenterMenuHelp.class);

    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private InitMenuHelp initMenuHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasProcessTemplateService paasProcessTemplateService;
    @Resource
    private CommonHelp commonHelp;


    @Override
    public List<String> alias() {
        return Arrays.asList(SystemAppMenuEnum.ORDER_CENTER.getAlias());
    }
    @Override
    public MenuInitVO initApp(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        PaasFormEntityExt paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(),menuInitDTO.getCorpid());
        if (Objects.isNull(paasFormEntity)) {
            paasFormEntity = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.PRODUCT.getCode(),menuInitDTO.getCorpid());
        }
        menuInitDTO.setProductForm(paasFormEntity);
        return initMenu(menuInitDTO, appMap);
    }

    /**
     * crm菜单初始化
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @return void
     * @throws XbbException
     */
    @Override
    public MenuInitVO initMenu(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            // 获取下应用id
            Long appId = menuInitDTO.getAppMap().get(SystemAppMenuEnum.ORDER_CENTER.getAlias()).getId();
            menuInitDTO.setAppId(appId);
            // 插入除分组外对应的菜单
            MenuFormAddBatchVO menuFormAddBatchVO = formAddBatch(menuInitDTO);
            if (Objects.isNull(menuFormAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<PaasMenuEntity> menuFormList = menuFormAddBatchVO.getMenuList();
            // 插入菜单对应的表单
            FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
            List<FormEntityAddDTO> formList = new ArrayList<>();
            // 通过分组菜单，得到需要插入的表单列表
            getFormList(formList, menuFormList, menuInitDTO.getCorpid());
            formAddBatchDTO.setFormList(formList);
            FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
            if (Objects.isNull(formAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入表单对应的字段解释
            formExplainAddBatch(menuInitDTO, formAddBatchVO);
            menuInitVO.setFormList(formAddBatchVO.getFormList());
            //formInsertList内的isProcessForm已处理
            if (!commonHelp.isOpenWorkFlow(menuInitDTO.getCorpid())) {
                ProcessOpenDistributorDTO processOpenDistributorDTO = new ProcessOpenDistributorDTO();
                //把登录信息copy进入dto
                BeanUtil.copyProperties(menuInitDTO, processOpenDistributorDTO);
                for (PaasFormEntity paasFormEntity : formAddBatchVO.getFormList()) {
                    if (Objects.equals(paasFormEntity.getIsProcessForm(), BasicConstant.ONE)) {
                        //把该form的appId、menuIdcopy进入dto
                        BeanUtil.copyProperties(paasFormEntity, processOpenDistributorDTO);
                        processOpenDistributorDTO.setFormId(paasFormEntity.getId());
                        paasProcessTemplateService.createProcess4Distributor(processOpenDistributorDTO);
                    }
                }
            }
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    @Override
    public void rollBackInit(MirrorRollBackDTO mirrorRollBackDTO, List<Long> installFormList, PaasFormEntity productFormEntity) throws XbbException {

    }

    public MenuInitVO initOrderOutStock(MenuInitDTO menuInitDTO) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            menuInitDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
            Map<String, Object> param = new HashMap<>();
            param.put("corpid", menuInitDTO.getCorpid());
            param.put("businessType", XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());
            param.put("distributorMark", BasicConstant.ZERO);
            param.put("del", BasicConstant.ZERO);
            List<PaasFormEntity> entity = paasFormModel.findEntity(param);
            PaasFormEntity paasFormEntity = entity.get(0);
            //获取应用ID 菜单ID
            Long appId = paasFormEntity.getAppId();
            Long menuId = paasFormEntity.getMenuId();
            menuInitDTO.setAppId(appId);
            FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
            List<FormEntityAddDTO> formList = new ArrayList<>();
            FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
            BeanUtil.copyProperties(paasFormEntity, formAddBatchDTO);
            formEntityAddDTO.setCorpid(menuInitDTO.getCorpid());
            formEntityAddDTO.setAppId(appId);
            formEntityAddDTO.setName("出库发货单");
            formEntityAddDTO.setBusinessType(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());
            formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formEntityAddDTO.setLabels(getAppDefaultLabel(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()));
            formEntityAddDTO.setCustomTitle(getAppDefaultTitle(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()));
            formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()));
            formEntityAddDTO.setBusinessRules("0");
            formEntityAddDTO.setMenuId(menuId);
            formEntityAddDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
            formList.add(formEntityAddDTO);
            // 通过分组菜单，得到需要插入的表单列表
            formAddBatchDTO.setFormList(formList);
            FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
            if (Objects.isNull(formAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入表单对应的字段解释
            formExplainAddBatch(menuInitDTO, formAddBatchVO);
            PaasFormEntity paasForm = formAddBatchVO.getFormList().get(0);
            // 插入启用发货配置项
            FormConfigEntity configEntity = new FormConfigEntity(menuInitDTO.getCorpid(), paasForm.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfigValue());
            formConfigModel.insert(configEntity);
            menuInitVO.setFormList(formAddBatchVO.getFormList());
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    /**
     * 添加表单字段解释
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @param formAddBatchVO 表单数据
     * @return 返回表单字段对象
     * @throws XbbException
     */
    public FormExplainAddBatchVO formExplainAddBatch(MenuInitDTO menuInitDTO, FormAddBatchVO formAddBatchVO) throws XbbException {
        FormExplainAddBatchVO formExplainAddBatchVO;
        try {
            List<PaasFormEntity> formResultList = formAddBatchVO.getFormList();
            FormExplainAddBatchDTO formExplainAddBatchDTO = new FormExplainAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formExplainAddBatchDTO);
            List<FormExplainAddDTO> formExplainList = new ArrayList<>();
            // 批次序列号解释需要都配置
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias(), menuInitDTO.getCorpid());
            boolean isUseBatch = Objects.nonNull(companyConfigEntity) && Objects.equals(companyConfigEntity.getConfigValue(), BasicConstant.IS_USE.toString());
            for (PaasFormEntity item : formResultList) {
                FormExplainAddDTO formExplainAddDTO = new FormExplainAddDTO();
                BeanUtil.copyProperties(item, formExplainAddDTO);
                formExplainAddDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
                formExplainAddDTO.setFormId(item.getId());
                String alias = XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias();
                // 初始化方法获取字段列表
                List<FieldAttrEntity> explainList = new ArrayList<>();
//                if (!InitExplainsHelper.EMPTY_EXPLAIN.contains(item.getBusinessType())) {
                    explainList = InitExplainsHelper.initFieldAttrEntity(alias,menuInitDTO.getProductForm(), null, 1);
//                }
                if (Objects.equals(item.getBusinessType(), XbbRefTypeEnum.REFUND.getCode())) {
                    out:
                    for (FieldAttrEntity attrEntity : explainList) {
                        if (Objects.equals(attrEntity.getAttr(), ReturnEnum.PRODUCTS.getAttr())) {
                            for (FieldAttrEntity subAttrEntity : attrEntity.getSubForm().getItems()) {
                                if (Objects.equals(subAttrEntity.getAttr(), SelectProductEnum.SOURCE_DOC.getAttr())) {
                                    subAttrEntity.setAttrName("源出库发货单");
                                    break out;
                                }
                            }
                        }
                    }
                }
                // 批次序列号解释需要都配置
                if (isUseBatch && Arrays.asList(XbbRefTypeEnum.REFUND.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode()).contains(item.getBusinessType())) {
                    // 这两个业务都是array_1
                    String productAttr = ReturnEnum.PRODUCTS.getAttr();
                    BatchSeqExplainHelp.getInstance().formatExplain4BatchAffectProductAttr(explainList, BasicConstant.IS_USE.toString(), productAttr);
                }
                formExplainAddDTO.setFormList(explainList);
                formExplainList.add(formExplainAddDTO);
            }
            formExplainAddBatchDTO.setFormExplainList(formExplainList);
            formExplainAddBatchVO = paasFormExplainService.addBatch(formExplainAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainAddBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainAddBatchVO;
    }

    /**
     * 批量添加表单
     * @author wujian
     * @date 2020/12/22 22:43
     * @param menuInitDTO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO
     * @throws XbbException
     */
    private MenuFormAddBatchVO formAddBatch(MenuInitDTO menuInitDTO) throws XbbException {
        MenuFormAddBatchVO menuFormAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            MenuFormAddBatchDTO orderCenterFormAddBatchDTO = new MenuFormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, orderCenterFormAddBatchDTO);
            orderCenterFormAddBatchDTO.setAppId(appId);
            List<MenuFormAddDTO> orderCenterFormMenuList = new ArrayList<>();
            for(OrderCenterMenuEnum orderCenterMenuEnum: OrderCenterMenuEnum.values()){
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setAppId(appId);
                menuFormAddDTO.setParentId(0L);
                menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                menuFormAddDTO.setAlias(orderCenterMenuEnum.getAlias());
                menuFormAddDTO.setName(orderCenterMenuEnum.getName());
                AccessLinkEnum accessLinkEnum = orderCenterMenuEnum.getAccessLinkEnum();
                menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
                menuFormAddDTO.setColor(accessLinkEnum.getColor());
                menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
                menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                menuFormAddDTO.setType(orderCenterMenuEnum.getType());
                menuFormAddDTO.setDistributorMark(1);
                orderCenterFormMenuList.add(menuFormAddDTO);
            }
            orderCenterFormAddBatchDTO.setMenuList(orderCenterFormMenuList);
            menuFormAddBatchVO = paasMenuService.addBatchFormMenu(orderCenterFormAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitOrderCenterMenuHelp.formAddBatch批量添加表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuFormAddBatchVO;
    }

    /**
     * 根据菜单获取表单列表
     * @author lee
     * @date 2019/1/24 18:43
     * @param formList 表单列表
     * @param menuList 菜单列表
     * @return 返回需要插入的表单列表
     * @throws XbbException 业务异常
     */
    public List<FormEntityAddDTO> getFormList(List<FormEntityAddDTO> formList, List<PaasMenuEntity> menuList, String corpid) throws XbbException{
        try {
            boolean openWorkflow = commonHelp.isOpenWorkFlow(corpid);
            for (PaasMenuEntity item : menuList) {
                FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
                BeanUtil.copyProperties(item, formEntityAddDTO);
                OrderCenterMenuEnum orderCenterMenuEnum = OrderCenterMenuEnum.getByAlias(item.getAlias());
                if (Objects.isNull(orderCenterMenuEnum)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                }
                formEntityAddDTO.setBusinessType(orderCenterMenuEnum.getCode());
                formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                formEntityAddDTO.setLabels(getAppDefaultLabel(orderCenterMenuEnum.getCode()));
                formEntityAddDTO.setCustomTitle(getAppDefaultTitle(orderCenterMenuEnum.getCode()));
                formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(orderCenterMenuEnum.getCode()));
                formEntityAddDTO.setBusinessRules("0");
                formEntityAddDTO.setMenuId(item.getId());
                if (Objects.equals(orderCenterMenuEnum, OrderCenterMenuEnum.RETURN) && !openWorkflow) {
                    formEntityAddDTO.setIsProcessForm(1);
                }
                formList.add(formEntityAddDTO);
            }
        }catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.getFormList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formList;
    }

}

